/*================================================================
*   Copyright (C) 2020 Sangfor Ltd. All rights reserved.
*   
*   文件名称：epoll_lt_svr.hpp
*   创 建 者：Ann
*   创建日期：2020年06月18日
*   描    述：
*
================================================================*/

#pragma once
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <vector>

#include "tcpsvr.hpp"

class EpollSvr
{
    public:
        EpollSvr()
        {
            epoll_fd_ = -1;
        }

        ~EpollSvr()
        {

        }

        bool InitSvr()
        {
            epoll_fd_ = epoll_create(10);
            if(epoll_fd_ < 0)
            {
                return false;
            }
            return true;
        }

        bool AddFd(int fd)
        {
            //1.组织事件结构
            struct epoll_event ev;
            ev.events = EPOLLIN;
            ev.data.fd = fd;
            int ret = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev);
            if(ret < 0)
            {
                perror("epoll_ctl");
                return false;
            }
            return true;
        }

        bool DeleteFd(int fd)
        {
            int ret = epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, NULL);
            if(ret < 0)
            {
                perror("epoll_ctl");
                return false;
            }
            return true;
        }

        bool EpollWait(std::vector<TcpSvr>* out)
        {
            //10
            struct epoll_event fd_arr[10];
            int ret = epoll_wait(epoll_fd_, fd_arr, sizeof(fd_arr)/sizeof(fd_arr[0]), -1);
            if(ret < 0)
            {
                perror("epoll_wait");
                return false;
            }
            else if(ret == 0)
            {
                printf("epollwait timeout\n");
                return false;
            }

            //防止数组越界
            if(ret > sizeof(fd_arr)/sizeof(fd_arr[0]))
            {
                ret = sizeof(fd_arr)/sizeof(fd_arr[0]);
            }

            //剩下的逻辑都是ret大于0的逻辑了
            for(int i = 0; i < ret; i++)
            {
               TcpSvr ts; 
               ts.SetFd(fd_arr[i].data.fd);
               out->push_back(ts);
            }
            return true;
        }
    private:
        //epoll操作句柄
        int epoll_fd_;
};

